﻿using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using Microsoft.CSharp;

namespace AChance.Func
{
    public static class FunService
    {
        public static class Soap
        {
            private static readonly Hashtable _htlSoapClient = new Hashtable();
            private static object CreateClient(string wsdlUrl)
            {
                //string @namespace = "AChance.Func.SoapWebService";
                try
                {
                    //获取WSDL   
                    WebClient wc = new WebClient();
                    Stream stream = wc.OpenRead(wsdlUrl);
                    //ServiceDescription sd = ServiceDescription.Read(stream);
                    //string classname = sd.Services[0].Name;
                    //ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
                    //sdi.AddServiceDescription(sd, "", "");
                    //CodeNamespace cn = new CodeNamespace(@namespace);

                    ////生成客户端代理类代码   
                    //CodeCompileUnit ccu = new CodeCompileUnit();
                    //ccu.Namespaces.Add(cn);
                    //sdi.Import(cn, ccu);
                    //CSharpCodeProvider icc = new CSharpCodeProvider();

                    ////设定编译参数   
                    //CompilerParameters cplist = new CompilerParameters();
                    //cplist.GenerateExecutable = false;
                    //cplist.GenerateInMemory = true;
                    //cplist.ReferencedAssemblies.Add("System.dll");
                    //cplist.ReferencedAssemblies.Add("System.XML.dll");
                    //cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
                    //cplist.ReferencedAssemblies.Add("System.Data.dll");

                    ////编译代理类   
                    //CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
                    //if (true == cr.Errors.HasErrors)
                    //{
                    //    StringBuilder sb = new StringBuilder();
                    //    foreach (CompilerError ce in cr.Errors)
                    //    {
                    //        sb.Append(ce.ToString());
                    //        sb.Append(Environment.NewLine);
                    //    }
                    //    throw new Exception(sb.ToString());
                    //}

                    //生成代理实例
                    //Assembly assembly = cr.CompiledAssembly;
                    //Type t = assembly.GetType(@namespace + "." + classname, true, true);
                    //return Activator.CreateInstance(t);
                    return null;
                }
                catch (Exception ex)
                {
                    FunLogs.LogError("调用Soap服务失败(" + wsdlUrl + ")", ex);
                    return null;
                }
            }
            public static SoapClient GetClient(String wsdlUrl)
            {
                SoapClient soapClient = (SoapClient)_htlSoapClient[wsdlUrl];
                if (soapClient == null)
                {
                    soapClient = new SoapClient(wsdlUrl);
                    _htlSoapClient[wsdlUrl] = soapClient;
                }
                return soapClient;
            }
            public class SoapClient
            {
                private readonly string _wsdlUrl = "";
                private object _client = null;
                public SoapClient(string wsdlUrl)
                {
                    _wsdlUrl = wsdlUrl;
                }
                public bool Invoke(string method, out object result)
                {
                    return Invoke(method, new object[0], out result);
                }
                public bool Invoke(string method, object arg, out object result)
                {
                    return Invoke(method, new object[1] { arg }, out result);
                }
                public bool Invoke(string method, object[] args, out object result)
                {
                    try
                    {
                        _client = _client ?? CreateClient(_wsdlUrl) ?? throw new Exception();
                        MethodInfo methodInfo = _client.GetType().GetMethod(method);
                        result = methodInfo.Invoke(_client, args);
                        return true;
                    }
                    catch (Exception ex)
                    {
                        result = "调用Soap服务中的方法失败(" + method + ")";
                        FunLogs.LogError(result.ToString(), ex);
                        return false;
                    }
                }
            }
        }
        public static class Rest
        {
            public static HttpClient GetClient(string uri)
            {
                if (uri.IsNullOrEmpty())
                    return null;
                //还缺少忽略安全检查的处理
                var httpClient = FunContext.Services.GetHttpClientFactory().CreateClient(uri);
                httpClient.BaseAddress = new Uri(uri);
                return httpClient;
            }
        }
    }
}
